﻿using System;

namespace LxCFD
{
    public partial class MGContact : IProvideContactTopology
    {
        // 这部分字段不是通过方法设置的，而是直接设置
        public MGZone O_Zone;
        public IndexNumber O_Index;
        public MGCell[] O_Cells;
        public MGFace[] O_Faces;

        public MGZone N_Zone;
        public IndexNumber N_Index;
        public MGCell[] N_Cells;
        public MGFace[] N_Faces;

        public IndexNumber InnerIndex;
        public MGPair[] Pairs;

        #region 接口IProvideContactDataForAMG
        public int[] GetOZoneCellOFaces(int cellIndex)
        {
            return O_Cells[cellIndex].OFaces;
        }
        public int[] GetNZoneCellOFaces(int cellIndex)
        {
            return N_Cells[cellIndex].OFaces;
        }
        public IndexNumber GetInnerIndex()
        {
            return InnerIndex;
        }
        #endregion
    }
    public partial class MGContact : IAMGSolvableContact
    {
        public AMGInContact InAMGSolver;

        protected double[] O_e;
        protected double[] O_eCommon;

        protected double[] N_e;
        protected double[] N_eCommon;

        public double[] ALUO;
        public double[] ALUN;

        protected IAMGSolvableContact FinerContact;
        public void SetArray(AMGInContact inAMGSolver)// Mesh.Contact contact)
        {
            this.InAMGSolver = inAMGSolver;// contact.AMGSolverInContact;

            this.O_e = O_Zone.e;
            this.O_eCommon = O_Zone.e_Common;

            this.N_e = N_Zone.e;
            this.N_eCommon = N_Zone.e_Common;

            LxTool.CheckCreateArray(ref ALUO, Pairs.Length);
            LxTool.CheckCreateArray(ref ALUN, Pairs.Length);
        }
        public void SetFineContact(IAMGSolvableContact finecontact)
        {
            this.FinerContact = finecontact;
        }
        public void Restrict_ALU(int taskIndex)
        {
            InnerIndex.FaceIDs.GetSeg(out int i1, out int endp1, taskIndex);
            for (; i1 < endp1; i1++)
            {
                FinerContact.Restrict_ALU(out ALUO[i1], out ALUN[i1], ref Pairs[i1]);
            }
        }
        public void Restrict_ALU(out double ALUO, out double ALUN, ref MGPair CoarsePair)
        {
            double aluo = 0, alun = 0;
            foreach (var pid in CoarsePair.FinePairs)
            {
                aluo += this.ALUO[pid];
                alun += this.ALUN[pid];
            }
            ALUO = aluo;
            ALUN = alun;
        }
    }
    public partial class MGContact : ISolvableContact
    {
        public void Copy_xArray(int taskIndex)
        {
            copyContact(O_e, N_e, taskIndex);
        }
        public void Copy_xCommonArray(int taskIndex)
        {
            copyContact(O_eCommon, N_eCommon, taskIndex);
        }
        protected void copyContact(double[] OArray, double[] NArray, int taskIndex)
        {
            {
                O_Index.CellIDs.GetSeg(out int i1, out int endp1, taskIndex);
                for (; i1 < endp1; i1++)
                {
                    double aluproduct = 0;
                    foreach (var pid in O_Cells[i1].OFaces)
                    {
                        aluproduct += ALUO[pid] * NArray[Pairs[pid].N_InnCell];
                    }
                    OArray[i1] = aluproduct;
                }
            }
            {
                N_Index.CellIDs.GetSeg(out int i1, out int endp1, taskIndex);
                for (; i1 < endp1; i1++)
                {
                    double aluproduct = 0;
                    foreach (var pid in N_Cells[i1].OFaces)
                    {
                        aluproduct += ALUN[pid] * OArray[Pairs[pid].O_InnCell];
                    }
                    NArray[i1] = aluproduct;
                }
            }
        }
    }
    public partial class MGContact 
    {
        public void Copy_yArray(int taskIndex)
        {
            copyContact(InAMGSolver.O_BiCGSolver.y, InAMGSolver.N_BiCGSolver.y, taskIndex);
        }
        public void Copy_zArray(int taskIndex)
        {
            copyContact(InAMGSolver.O_BiCGSolver.z, InAMGSolver.N_BiCGSolver.z, taskIndex);
        }
    }
}
